<?php

namespace App\Library\Payment\Alipay;

use Alipay\EasySDK\Kernel\Factory;
use Alipay\EasySDK\Kernel\Util\ResponseChecker;
use App\Helpers\LogHelper;
use Exception;
use Throwable;

/**
 *
 */
class AlipayApi extends BaseAlipayApi
{
	/**
	 * @param string $subject       标题
	 * @param string $orderNo       订单号
	 * @param string $orderPrice    支付金额
	 * @param array  $batchOptional 额外参数
	 * @return array
	 * @throws Exception
	 */
	public function appPay(string $subject, string $orderNo, string $orderPrice, array $batchOptional = []): array
	{
		try {
			// 设置参数
			Factory::setOptions($this->getOptions());

			if (!empty($batchOptional)) {
				$this->setBatchOptional($batchOptional);
			}

			// 发起API调用
			$result = Factory::payment()->app()->pay($subject, $orderNo, $orderPrice);
			LogHelper::info('payment-ali', $result);

			// 处理响应
			$responseChecker = new ResponseChecker();
			if (!$responseChecker->success($result)) {
				throw new Exception('获取预支付单号：支付接口调用失败，原因:' . $result->msg . ',' . $result->subCode);
			}

			return [
				'body' => $result->body,
			];
		} catch (Exception $e) {
			LogHelper::info('payment-ali', $e);

			throw new Exception($e->getMessage());
		}
	}

	/**
	 * 验证支付回调
	 *
	 * @param $params
	 * @return bool
	 * @throws Exception
	 */
	public function verifyNotify($params): bool
	{
		try {
			// 设置参数
			Factory::setOptions($this->getOptions());
			// 发起API调用
			return Factory::payment()->common()->verifyNotify($params);
		} catch (Exception $e) {
			throw new Exception($e->getMessage());
		}
	}


	/**
	 * 主动查询支付结果
	 *
	 * @param string $orderNo 订单号
	 * @return array
	 * @throws Exception
	 * @throws Throwable
	 */
	public function query(string $orderNo): array
	{
		try {
			// 设置参数
			Factory::setOptions($this->getOptions());

			// 发起API调用
			$result = Factory::payment()->common()->query($orderNo);
			LogHelper::info('payment-ali', $result);

			// 处理响应
			$responseChecker = new ResponseChecker();
			$status          = $responseChecker->success($result);
			if (!$status) {
				throw new Exception('查询支付：支付接口调用失败，原因:' . $result->msg . ',' . $result->subCode);
			}

			switch ($result->tradeStatus) {
				case 'WAIT_BUYER_PAY':
					$status = self::QUERY_PAY_STATUS_WAIT; // 未付款
					break;
				case 'TRADE_CLOSED':
					$status = self::QUERY_PAY_STATUS_CLOSED; // 未付款交易超时关闭，或支付完成后全额退款
					break;
				case 'TRADE_SUCCESS':
					$status = self::QUERY_PAY_STATUS_SUCCESS; // 交易支付成功
					break;
				default:
					$status = self::QUERY_PAY_STATUS_WAIT;
			}

			return [
				'orderNo'       => $result->outTradeNo ?? '',
				'status'        => $status,
				'totalAmount'   => intval($result->totalAmount * 100) ?? 0,
				'transactionId' => $result->tradeNo ?? '',
				'payTime'       => $result->sendPayDate ?? '',
			];
		} catch (Throwable $exception) {
			LogHelper::info('payment-ali', $exception);

			if (strpos($exception->getMessage(), 'ACQ.TRADE_NOT_EXIST') !== false) {
				return [
					'orderNo'       => '',
					'status'        => self::QUERY_PAY_STATUS_NOT_FOUND,
					'totalAmount'   => 0,
					'transactionId' => '',
					'payTime'       => '',
				];
			}
			throw $exception;
		}
	}

	/**
	 * 关闭订单
	 *
	 * @return void
	 * @throws Exception
	 */
	public function cancel(string $orderNo)
	{
		try {
			// 设置参数
			Factory::setOptions($this->getOptions());

			// 发起API调用
			$result          = Factory::payment()->common()->close($orderNo);
			LogHelper::info('payment-ali', $result);
			$responseChecker = new ResponseChecker();
			$status          = $responseChecker->success($result);
			if (!$status && !$result->subCode == 'ACQ.TRADE_NOT_EXIST') {
				throw new Exception('取消支付：支付接口调用失败，原因:' . $result->msg . ',' . $result->subCode);
			}
		} catch (Exception $exception) {
			LogHelper::info('payment', ['exceptionCode' => $exception->getCode(), 'exceptionMessage' => $exception->getMessage()]);
		}
	}
}